package com.ruoyi.wechat.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.wechat.service.IWxAccountService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 微信入口控制器
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/wx/portal")
public class WxPortalController extends BaseController
{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private IWxAccountService wxAccountService;

    /**
     * 微信服务器验证
     */
    @GetMapping("/{appid}")
    public String authGet(@PathVariable String appId,
                         @RequestParam(name = "signature", required = false) String signature,
                         @RequestParam(name = "timestamp", required = false) String timestamp,
                         @RequestParam(name = "nonce", required = false) String nonce,
                         @RequestParam(name = "echostr", required = false) String echostr)
    {
        this.logger.info("\n接收到来自微信服务器的认证消息：signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]",
                signature, timestamp, nonce, echostr);

        if (this.wxMpService.checkSignature(timestamp, nonce, signature))
        {
            return echostr;
        }
        return "非法请求";
    }

    /**
     * 接收微信消息
     */
    @PostMapping("/{appid}")
    public String post(@PathVariable String appId,
                       @RequestBody String requestBody,
                       @RequestParam("signature") String signature,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce,
                       @RequestParam(name = "encrypt_type", required = false) String encType,
                       @RequestParam(name = "msg_signature", required = false) String msgSignature)
    {
        this.logger.info("\n接收微信请求：[signature=[{}], timestamp=[{}], nonce=[{}], encType=[{}], msgSignature=[{}]]",
                signature, timestamp, nonce, encType, msgSignature);

        this.logger.info("\n消息内容：{}", requestBody);

        if (!this.wxMpService.checkSignature(timestamp, nonce, signature))
        {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }

        String out = null;
        if (encType == null)
        {
            // 明文传输的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody);
            WxMpXmlOutMessage outMessage = this.route(inMessage);
            if (outMessage == null)
            {
                return "";
            }
            out = outMessage.toXml();
        }
        else if ("aes".equals(encType))
        {
            // aes加密的消息
            WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, this.wxMpService.getWxMpConfigStorage(),
                    timestamp, nonce, msgSignature);
            this.logger.debug("\n消息解密后内容为：\n{} ", inMessage.toString());
            WxMpXmlOutMessage outMessage = this.route(inMessage);
            if (outMessage == null)
            {
                return "";
            }
            out = outMessage.toEncryptedXml(this.wxMpService.getWxMpConfigStorage());
        }

        this.logger.debug("\n组装回复信息：{}", out);
        return out;
    }

    private WxMpXmlOutMessage route(WxMpXmlMessage message)
    {
        try
        {
            // 这里可以根据消息类型进行不同的处理
            switch (message.getMsgType())
            {
                case EVENT:
                    return handleEventMessage(message);
                case TEXT:
                    return handleTextMessage(message);
                case IMAGE:
                    return handleImageMessage(message);
                case VOICE:
                    return handleVoiceMessage(message);
                case VIDEO:
                    return handleVideoMessage(message);
                case SHORTVIDEO:
                    return handleShortVideoMessage(message);
                case LOCATION:
                    return handleLocationMessage(message);
                case LINK:
                    return handleLinkMessage(message);
                default:
                    return null;
            }
        }
        catch (Exception e)
        {
            this.logger.error("处理消息失败", e);
            return null;
        }
    }

    /**
     * 处理事件消息
     */
    private WxMpXmlOutMessage handleEventMessage(WxMpXmlMessage message)
    {
        String event = message.getEvent();
        this.logger.info("收到事件消息：{}", event);

        switch (event)
        {
            case "subscribe":
                return WxMpXmlOutMessage
                        .TEXT()
                        .content("感谢您的关注！欢迎来到我们的商城！")
                        .fromUser(message.getToUser())
                        .toUser(message.getFromUser())
                        .build();
            case "unsubscribe":
                this.logger.info("用户取消关注：{}", message.getFromUser());
                return null;
            case "CLICK":
                return handleMenuClick(message);
            case "VIEW":
                return handleMenuView(message);
            default:
                return null;
        }
    }

    /**
     * 处理文本消息
     */
    private WxMpXmlOutMessage handleTextMessage(WxMpXmlMessage message)
    {
        String content = message.getContent();
        this.logger.info("收到文本消息：{}", content);

        // 简单的自动回复
        if ("商城".equals(content) || "shop".equalsIgnoreCase(content))
        {
            return WxMpXmlOutMessage
                    .TEXT()
                    .content("欢迎来到我们的商城！\n点击下方菜单开始购物吧！")
                    .fromUser(message.getToUser())
                    .toUser(message.getFromUser())
                    .build();
        }

        return WxMpXmlOutMessage
                .TEXT()
                .content("您好！感谢您的留言，我们会尽快回复您！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理图片消息
     */
    private WxMpXmlOutMessage handleImageMessage(WxMpXmlMessage message)
    {
        this.logger.info("收到图片消息：{}", message.getPicUrl());
        return WxMpXmlOutMessage
                .TEXT()
                .content("收到您发送的图片，感谢您的分享！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理语音消息
     */
    private WxMpXmlOutMessage handleVoiceMessage(WxMpXmlMessage message)
    {
        this.logger.info("收到语音消息：{}", message.getMediaId());
        return WxMpXmlOutMessage
                .TEXT()
                .content("收到您发送的语音，感谢您的分享！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理视频消息
     */
    private WxMpXmlOutMessage handleVideoMessage(WxMpXmlMessage message)
    {
        this.logger.info("收到视频消息：{}", message.getMediaId());
        return WxMpXmlOutMessage
                .TEXT()
                .content("收到您发送的视频，感谢您的分享！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理小视频消息
     */
    private WxMpXmlOutMessage handleShortVideoMessage(WxMpXmlMessage message)
    {
        this.logger.info("收到小视频消息：{}", message.getMediaId());
        return WxMpXmlOutMessage
                .TEXT()
                .content("收到您发送的小视频，感谢您的分享！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理位置消息
     */
    private WxMpXmlOutMessage handleLocationMessage(WxMpXmlMessage message)
    {
        this.logger.info("收到位置消息：{}, {}", message.getLocationX(), message.getLocationY());
        return WxMpXmlOutMessage
                .TEXT()
                .content("收到您发送的位置信息，感谢您的分享！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理链接消息
     */
    private WxMpXmlOutMessage handleLinkMessage(WxMpXmlMessage message)
    {
        this.logger.info("收到链接消息：{}", message.getUrl());
        return WxMpXmlOutMessage
                .TEXT()
                .content("收到您分享的链接，感谢您的分享！")
                .fromUser(message.getToUser())
                .toUser(message.getFromUser())
                .build();
    }

    /**
     * 处理菜单点击事件
     */
    private WxMpXmlOutMessage handleMenuClick(WxMpXmlMessage message)
    {
        String eventKey = message.getEventKey();
        this.logger.info("菜单点击事件：{}", eventKey);

        switch (eventKey)
        {
            case "MALL_HOME":
                return WxMpXmlOutMessage
                        .TEXT()
                        .content("欢迎来到商城首页！\n\n您可以：\n1. 浏览商品\n2. 查看优惠\n3. 下单购买")
                        .fromUser(message.getToUser())
                        .toUser(message.getFromUser())
                        .build();
            case "MALL_ORDER":
                return WxMpXmlOutMessage
                        .TEXT()
                        .content("您的订单查询功能正在开发中，敬请期待！")
                        .fromUser(message.getToUser())
                        .toUser(message.getFromUser())
                        .build();
            case "MALL_USER":
                return WxMpXmlOutMessage
                        .TEXT()
                        .content("个人中心功能正在开发中，敬请期待！")
                        .fromUser(message.getToUser())
                        .toUser(message.getFromUser())
                        .build();
            default:
                return WxMpXmlOutMessage
                        .TEXT()
                        .content("感谢您的点击！")
                        .fromUser(message.getToUser())
                        .toUser(message.getFromUser())
                        .build();
        }
    }

    /**
     * 处理菜单跳转事件
     */
    private WxMpXmlOutMessage handleMenuView(WxMpXmlMessage message)
    {
        this.logger.info("菜单跳转事件：{}", message.getEventKey());
        return null; // 跳转事件不需要回复
    }
}
